Conversation
Signed-off-by: Dan Zhang <danzh@google.com>
Signed-off-by: Dan Zhang <danzh@google.com>
|
/assign @venilnoronha, @mattklein123 , @sbelair2, @alyssawilk, @mpw, @jmarantz, @jrajahalme, @sesmith177, @ggreenway. Add whoever commented on #5171. Feel free to unassign yourself if not interested any more. |
|
🙀 Error while processing event: |
Signed-off-by: Dan Zhang <danzh@google.com>
Signed-off-by: Dan Zhang <danzh@google.com>
|
/assign @venilnoronha |
|
@danzh1989 error is because of the commas. you can mention all users in the same "/assign" command, just no commas. |
Signed-off-by: Dan Zhang <danzh@google.com>
| * We probably still need some method similar to this one for | ||
| * evconnlistener_new(). Or We can move it to IoSocketHandle and down cast the | ||
| * IoHandle to IoSocketHandle wherever needed. | ||
| */ |
There was a problem hiding this comment.
My opinion is that it would be cleaner to move this to the derived IoSocketHandle- what does the fd() method resolve to for interfaces that are not sockets? Either that, or there can be a generic method to manage a descriptor of sorts, such that for sockets, the descriptor is really just the fd. And for other interfaces it might be a session id, etc.
There was a problem hiding this comment.
I would prefer a generic method to return some sorts of identity which can be used differently for different implementation. WDYT?
There was a problem hiding this comment.
@danzh1989 @sbelair2 I don't think I'm grokking this convo fully. Can one or both of you expand? I don't think we should still need this method so I'm likely missing something.
There was a problem hiding this comment.
@mattklein123 Maybe I missed some earlier conversation, but what shall be passed into evconnlistener_new() if there is no fd() or something similar in interface?
There was a problem hiding this comment.
We could probably figure out an interface strategy in which the socket actually creates the listener somehow, but for now, I would probably just do a dynamic_cast. It's a little ugly, but VPP or similar will have to have their own listener implementation, so it should fit together OK? Thoughts?
There was a problem hiding this comment.
@mattklein123 Do you mean to make fd() a method to IoSocketHandle only and dynamic_cast the IoHhandle object when we create listener? That sounds reasonable to me.
There was a problem hiding this comment.
Yes that's what I meant. IMO that's OK for now.
| virtual std::unique_ptr<IoHandle> dup() PURE; | ||
|
|
||
| virtual IoHandleCallIntResult shutdown(int how) PURE; | ||
| }; |
There was a problem hiding this comment.
It seems to me that there is probably no point in defining the template class IoHandleCallResult if all the virtual methods in the base class are all IoHandleCallResult or IoHandleCallResult<ssize_t>. I think we need to examine if there are any return values that can be other than integer types. If there are other interfaces that need this (I'm not saying that VPP is one of them), then won't these virtual methods preclude them?
There was a problem hiding this comment.
@danzh2010 I do want to say that I like the direction where this is going.
There was a problem hiding this comment.
Are you concerned about some implementations of same method whose return a type is different from what is declared here? For such method, I would say same purpose can be achieved by adding another new method to the interface.
If IoHandleCallResult and IoHandleCallResult<ssize_t> are the only two return types we need, what would you like the IoHandleCallResult to be without template?
There was a problem hiding this comment.
@danzh2010 Sorry, forgot about this. I'm only thinking that we should not preclude further options, but maybe that's just too much caution? Right now I cannot think of other return types we might need, but that doesn't mean that such a need won't come up later.
There was a problem hiding this comment.
Now we have IoHandleCallResult<std::bitset<2>>
mpwarres
left a comment
There was a problem hiding this comment.
From the perspective of what will work for QUIC, I think this should work fine, once sendmmsg/recvmmsg methods are added.
I feel like this interface has the potential to help with doing recvmsg from N sockets using SO_REUSEPORT, since it helps to hide the underlying FD (and thus may make it possible to have N FDs instead of just one), but I don't have a clear enough picture of this to suggest anything yet.
I think there's a top-level question to be answered (not by me) on whether the IoHandle API should be socket-style (like here) as opposed to more abstract. As an example, whether readv/writev should operate on Buffer::Instances rather than iovecs, or whether methods should indicate failure via exceptions rather than int error codes, etc. One argument in favor of the current form is that (a) it's a nice, step-wise change from previous code, and (b) now that all operations go through methods on IoHandle, they can always be changed to be higher-level in the future, incrementally.
include/envoy/network/io_handle.h
Outdated
| /** | ||
| * Wrap getsockname() | ||
| */ | ||
| virtual IoHandleCallIntResult getIoHandleName(const Network::Address::Instance& address) PURE; |
There was a problem hiding this comment.
nit: how will getIoHandleName() and getPeerName() actually return the name? They take const params, whereas getsockname() takes a mutable out-param. (Though making the Network::Address::Instance param non-const may not be sufficient, since Address::Instance isn't mutable in a way that allows it to be changed to a different address.)
There was a problem hiding this comment.
yeah we will need some type of out param for these functions. You could either do an out param is an actual parameter, or have it return a struct of a result code and the address. I actually prefer the latter but I don't feel strongly about it.
There was a problem hiding this comment.
I would prefer an output param of Network::Address::Instance type.
| virtual IoHandleCallIntResult bind(const Network::Address::Instance& address) PURE; | ||
|
|
||
| virtual IoHandleCallIntResult connect(const Network::Address::Instance& server_address) PURE; | ||
|
|
There was a problem hiding this comment.
For UDP we will need methods that provide the equivalent of sendmmsg and recvmmsg.
There was a problem hiding this comment.
Added. Not sure if envoy has something equivalent to mmsghdr or msghdr.
There was a problem hiding this comment.
I'm not aware of any equivalent currently--the closest I can think of would be the UdpData struct @conqerAtapple added recently. Though if we wanted to use that, we would have to add analogues for msghdr.msg_control and msghdr.msg_flags fields. @conqerAtapple , do you have an opinion?
| /** | ||
| * Wrap setsockopt() | ||
| */ | ||
| virtual IoHandleCallIntResult setIoHandleOption(int level, int optname, const void* optval, |
There was a problem hiding this comment.
I would suggest we use an enum for the options we care about. The one gotcha here is IIRC we have some capability in the config to actually set options that the code doesn't know about, by int, so maybe this isn't possible and we need to keep this? Thoughts?
There was a problem hiding this comment.
Would there be potential crash if envoy fails to map the value set in config and the enum defined here? If so, introducing enum for socket option can be error-prone.
There was a problem hiding this comment.
Right I think if we have a config option to set an int, we need to leave it as is.
include/envoy/network/io_handle.h
Outdated
| /** | ||
| * Wrap fcntl(fd_, F_SETFL...) | ||
| */ | ||
| virtual IoHandleCallIntResult setIoHandleFlag(int flag) PURE; |
There was a problem hiding this comment.
enum for options we care about?
There was a problem hiding this comment.
Added enum IoHandleFlag, but we only used O_NONBLOCK so far.
include/envoy/network/io_handle.h
Outdated
| /** | ||
| * Wrap fcntl(fd_, F_GETFL...) | ||
| */ | ||
| virtual IoHandleCallIntResult getIoHandleFlag() PURE; |
There was a problem hiding this comment.
Return a bit set of enums that we care about?
There was a problem hiding this comment.
do you mean std::bitset or just int?
mattklein123
left a comment
There was a problem hiding this comment.
Thanks this is great to get this discussion going. I dropped in various comments.
Signed-off-by: Dan Zhang <danzh@google.com>
Signed-off-by: Dan Zhang <danzh@google.com>
| virtual IoHandleCallIntResult bind(const Network::Address::Instance& address) PURE; | ||
|
|
||
| virtual IoHandleCallIntResult connect(const Network::Address::Instance& server_address) PURE; | ||
|
|
There was a problem hiding this comment.
I'm not aware of any equivalent currently--the closest I can think of would be the UdpData struct @conqerAtapple added recently. Though if we wanted to use that, we would have to add analogues for msghdr.msg_control and msghdr.msg_flags fields. @conqerAtapple , do you have an opinion?
|
|
||
| namespace Envoy { | ||
|
|
||
| namespace Buffer { |
There was a problem hiding this comment.
nit: prefer include header vs. forward decl unless there is a circular dependency, same below.
There was a problem hiding this comment.
include/envoy/buffer/buffer.h will depend on io_handle.h, so will network/address.h.
include/envoy/network/io_handle.h
Outdated
| class IoError { | ||
| public: | ||
| enum class IoErrorCode { | ||
| NoError = 0, |
There was a problem hiding this comment.
nit: add comments for what each of these mean generically to Envoy?
include/envoy/network/io_handle.h
Outdated
| IoHandle() {} | ||
| enum class ShutdownType { Read = 0, Write, Both }; | ||
|
|
||
| enum class IoHandleFlag { NonBlock = 1, Append = 2 }; |
There was a problem hiding this comment.
nit: Why explicitly number this?
There was a problem hiding this comment.
...and ditto for the enums above (ShutdownType, IOError, ...).
There was a problem hiding this comment.
nit: Why explicitly number this?
This enum's values should be mapped to 2^n if we want it to fit into bitset.
There was a problem hiding this comment.
OK, can you use 0x1, 0x10, etc. do make that clear?
There was a problem hiding this comment.
I assume you meant 0b1, 0b10. Done
There was a problem hiding this comment.
Oops sorry I meant 0x1, 0x2, 0x4, 0x10, etc. but either way.
| /** | ||
| * Wrap fcntl(fd_, F_SETFL...) | ||
| */ | ||
| virtual IoHandleCallIntResult setIoHandleFlag(std::bitset<2> flag) PURE; |
There was a problem hiding this comment.
Can we document what the bitset actually means? Potentially with an enum of each bit?
There was a problem hiding this comment.
I think you can just refer back to the enum which will have 0x1, etc. for docs?
| * We probably still need some method similar to this one for | ||
| * evconnlistener_new(). Or We can move it to IoSocketHandle and down cast the | ||
| * IoHandle to IoSocketHandle wherever needed. | ||
| */ |
There was a problem hiding this comment.
We could probably figure out an interface strategy in which the socket actually creates the listener somehow, but for now, I would probably just do a dynamic_cast. It's a little ugly, but VPP or similar will have to have their own listener implementation, so it should fit together OK? Thoughts?
|
|
||
| class IoError { | ||
| public: | ||
| enum class IoErrorCode { |
There was a problem hiding this comment.
if this merges after #5772, can we also update that API to reference IOError here rather than do what it's doing?
Also IMO IOError should not be underneath the Network namespace, as this also makes sense for non-networked I/O.
There was a problem hiding this comment.
This PR won't be checked in as a whole. Otherwise, all the implementations of these interfaces will have to be there and replacing all the direct sys call's to fd. I plan to check in the methods one by one in following PR's, starting from #5171 which will very likely has IoErrorCode definition.
Where would you like to place IoError?
And it will be great if #5772 can have TODO for switching to IoError if it's checked in first.
Signed-off-by: Dan Zhang <danzh@google.com>
Signed-off-by: Dan Zhang <danzh@google.com>
SGTM |
|
This pull request has been automatically marked as stale because it has not had activity in the last 7 days. It will be closed in 7 days if no further activity occurs. Please feel free to give a status update now, ping for review, or re-open when it's ready. Thank you for your contributions! |
Signed-off-by: Dan Zhang <danzh@google.com>
|
I updated IoError interface according to the discussion in #5171. This is to address memory allocation problem for frequent error like EAGAIN. |
|
This pull request has been automatically marked as stale because it has not had activity in the last 7 days. It will be closed in 7 days if no further activity occurs. Please feel free to give a status update now, ping for review, or re-open when it's ready. Thank you for your contributions! |
|
This pull request has been automatically closed because it has not had activity in the last 14 days. Please feel free to give a status update now, ping for review, or re-open when it's ready. Thank you for your contributions! |
Propose changes to IoHandle interface to wrap socket system calls. This PR is for discussion purpose, so that the IoHandle interface can be used as base class for both socket and non-socket implementations. It won't be checked in as the implementation for these interfaces will go in one by one in following PR's.
Part of #4546 #2557